package top.shenluw.tools.lyric

import org.apache.commons.cli.*
import java.io.File
import java.io.FileInputStream
import java.io.FileOutputStream


fun main(args: Array<String>) {
    val options = Options()

    options.addOption(
        Option
            .builder("i")
            .hasArg()
            .required()
            .desc("输入文件路径: ./testfile")
            .build()
    )
    options.addOption(Option("it", true, "输入文件格式: NetEase"))
    options.addOption(Option("o", true, "输出目录: ./test"))
    options.addOption(
        Option.builder("ot")
            .hasArg()
            .desc("输出文件格式: [LRC,SRT]  -ot LRC -ot SRT")
            .build()
    )

    val help = HelpFormatter()
    help.printHelp("cv", options)

    val parser = DefaultParser()
    try {
        val commandLine = parser.parse(options, args)

        val inFile = File(commandLine.getOptionValue("i"))
        val outPath = commandLine.getOptionValue("o")
        val outFile = if (outPath == null) {
            File("./")
        } else {
            File(outPath)
        }

        val ots = commandLine.getOptionValues("ot")
        val outTypes: List<LyricType>
        if (ots.isNullOrEmpty()) {
            outTypes = arrayListOf(LyricType.SRT, LyricType.LRC)
        } else {
            outTypes = ots.map {
                LyricType.valueOf(it)
            }
        }

        Application().run(inFile, LyricType.NetEase, outFile, outTypes)
        println("转换完成")
    } catch (exp: ParseException) {
        System.err.println("Parsing failed.  Reason: " + exp.message)
    }
}


class Application {

    private fun <A, B> combination(list1: Iterable<A>, list2: Iterable<B>): MutableSet<Pair<A, B>> {

        val result = mutableSetOf<Pair<A, B>>()

        list1.forEach { a ->
            list2.forEach { b ->
                result.add(Pair(a, b))
            }
        }

        return result

    }

    fun run(inFile: File, srcType: LyricType, outDir: File, outTypes: Iterable<LyricType>) {
        if (!inFile.exists()) {
            println("输入文件不存在")
            return
        }
        if (outDir.isDirectory && outDir.exists()) {

        } else {
            outDir.mkdirs()
        }
        var lyricReader: LyricReader? = null
        val inputStream = FileInputStream(inFile)
        if (srcType == LyricType.NetEase) {
            lyricReader = NetEaseLyricReader()
        }

        if (lyricReader == null) {
            println("输入格式不支持")
            return
        }
        val lyrics: MutableList<LyricInfo>
        try {
            lyrics = lyricReader.read(inputStream)
        } catch (e: Exception) {
            println("输入格式不符合要求")
            return
        }

        combination(outTypes, lyrics)
            .forEach {
                val writer: LyricWriter
                if (it.first == LyricType.LRC) {
                    writer = NetEaseLRCLyricWriter()
                } else if (it.first == LyricType.SRT) {
                    writer = NetEaseSRTLyricWriter()
                } else {
                    println("输出格式不支持")
                    return
                }
                try {
                    var tag: String = if (it.second.tag != null) {
                        "_${it.second.tag}"
                    } else ""
                    val out =
                        FileOutputStream(
                            File(
                                outDir,
                                "lyric_${inFile.nameWithoutExtension}$tag.${it.first.extension}"
                            )
                        )
                    writer.writer(it.second, out)
                    out.close()
                } catch (e: Exception) {
                    println("歌词输出失败： ${it.first}")
                    println(e.message)
                }
            }
    }
}